<?php
/**
 * 核心函数
 *
 */

function jclass($class_name) 
{
	return Load::model($class_name);
}

function jmodel($model_name) 
{
	return Load::model($model_name);
}

function jlib($lib_name) 
{
	return Load::lib($lib_name, 1);
}

function jlogic($logic_name) 
{
	return Load::logic($logic_name, 1);
}

function jtable($table_name) 
{
	return Load::table($table_name);
}

function jaccess($mod, $code = '', $uid = MEMBER_ID, $is_admin = 0) 
{
	$ret = false;
	if(($mh = & Obj::registry('MemberHandler'))) 
	{
		$ret = (($mh->access($mod, $code, $is_admin, $uid)) ? true : false);
	}
	return $ret;
}

function jhtmlspecialchars($string, $flags = ENT_COMPAT, $charset = NULL)
{
	if(is_null($charset))
	{
		$charset = $GLOBALS['_J']['charset'];
		$charset = ('utf-8' == $charset ? 'UTF-8' : ('gbk' == $charset ? 'GB2312' : 'ISO-8859-1'));
	}
	return htmlspecialchars($string, $flags, $charset);
}

function jfilter($val, $filter)
{
	$filter = strtolower($filter);
	switch ($filter)
	{
		case 'int': $val = (int) $val; break;
		case 'float': $val = (float) $val; break;
		case 'bool': 
		case 'boolean': $val = (bool) $val; break;
		case 'num': 
		case 'number': $val = (is_numeric($val) ? $val : 0); break;
		case 'trim': $val = trim($val); break;
		case 'txt': $val = trim(jhtmlspecialchars(strip_tags($val))); break;
		case 'html': $val = jhtmlspecialchars($val); break;
		case 'url': $val = (($val && preg_match("/^(https?\:\/\/|www\.)([A-Za-z0-9_\-]+\.)+[A-Za-z]{2,4}(\/[\w\d\/=\?%\-\&_~`@\[\]\:\+\#]*([^<>\'\"\n])*)?$/", $val)) ? $val : false); break;
		case 'email': $val = (($val && false !== strpos($val, '@') && preg_match('~^[-_.[:alnum:]]+@((([[:alnum:]]|[[:alnum:]][[:alnum:]-]*[[:alnum:]])\.)+([a-z]{2,4})|(([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])\.){3}([0-9][0-9]?|[0-1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]))$~i', $val)) ? $val : false); break;
		case 'zip': $val = (($val && is_numeric($val) && preg_match('~^\d{6}$~', $val)) ? $val : false); break;
		case 'qq': $val = (($val && is_numeric($val) && preg_match('~^[1-9]\d{4,10}$~')) ? $val : false); break;
		case 'mobile': $val = (($val && is_numeric($val) && preg_match('~^((?:13|15|18)\d{9}|0(?:10|2\d|[3-9]\d{2})[1-9]\d{6,7})$~', $val)) ? $val : false); break;
		case 'chinese': $val = (($val && preg_match('~^(?:[\x7f-\xff][\x7f-\xff])+$~')) ? $val : false); break;
		case 'english': $val = (($val && preg_match('~^[A-Za-z]+$~')) ? $val : false); break;
		case 'username': $val = (($val && !is_numeric($val) && preg_match('~^[\w\d_]{1, 30}$~', $val)) ? $val : false); break;
		default:
			break;
	}
	return $val;
}

function jget($key, $filter='', $method='PG')
{
	return get_param($key, $method, $filter);
}

function jerror($msg, $code=0, $output='')
{
	$rets = array(
			'error' => 1,
			'msg' => $msg,
	);
	if($code)
	{
		$rets['code'] = $code;
	}
	if($output && in_array($output, array('exit', 'die', 'json_error')))
	{
		$output($msg);
	}
	else
	{
		return $rets;
	}
}

function jdefine($name, $value, $case_insensitive = false)
{
	if(defined($name) && $value !== constant($name))
	{
		exit($name . ' is defined');
	}
	define($name, $value, $case_insensitive);
}

function get_param($key, $method='PG', $filter='') 
{
	$method = strtoupper($method);
	switch ($method) 
	{
		case 'POST': 
		case 'P': $var = &$_POST; break;
		case 'GET': 
		case 'G': $var = &$_GET; break;
		case 'COOKIE': 
		case 'C': $var = &$_COOKIE; break;
		default:
			if(isset($_POST[$key])) 
			{
				$var = &$_POST;
			} 
			else 
			{
				$var = &$_GET;
			}
			break;
	}
	$val = (isset($var[$key]) ? $var[$key] : null);
	if($filter) 
	{
		$val = jfilter($val, $filter);
	}
	return $val;
}

function array_remove_empty($array)
{
	if(!$array)
	{
		return array();
	}
	foreach($array as $key=>$val)
	{
		if (!$val) 
		{
			unset($array[$key]);
		}
	}
	return $array;
}

class Load 
{
	static function functions($name) 
	{
		return @include_once(ROOT_PATH . 's_include/function/' .$name.'.func.php');
	}
	
	static function logic($name, $init=0) 
	{
		if(!$init) 
		{
			return @include_once(ROOT_PATH . 's_include/logic/' .$name.'.logic.php');
		} 
		else 
		{
			static $S_logics = array();
			if(is_null($S_logics[$name])) 
			{
				$class_name = '';
				if(false !== strpos($name, '_')) 
				{
					$ns = explode('_', $name);
					foreach($ns as $n) 
					{
						$class_name .= ucfirst($n);
					}
				} 
				else 
				{
					$class_name = ucfirst($name);
				}
				$class_name .= 'Logic';
				if(!(@include_once ROOT_PATH . 's_include/logic/' . $name . '.logic.php') && !class_exists($class_name)) 
				{
					exit('logic ' . $name . ' is not exists');
				}
				$S_logics[$name] = new $class_name();
			}
			return $S_logics[$name];
		}
	}
	
	static function lib($name, $init=0) 
	{
		if(!$init) 
		{
			return @include_once(ROOT_PATH . 's_include/lib/' .$name . '.han.php');
		} 
		else 
		{
			static $S_libs = array();
			if(is_null($S_libs[$name])) 
			{
				$class_name = ucfirst($name) . 'Handler';
				if(!(@include_once ROOT_PATH . 's_include/lib/' . $name . '.han.php') && !class_exists($class_name)) 
				{
					exit('lib ' . $name . ' is not exists');
				}
				$S_libs[$name] = new $class_name();
			}
			return $S_libs[$name];
		}
	}
	
	static function file($name) 
	{
		$folder = 's_include/class/';
		$class_name = str_replace(array('/'), '_', $name);
		if(!(@include_once ROOT_PATH . $folder . $name . '.class.php') && !class_exists($class_name)) 
		{
			return false;
		}
		return $class_name;
	}
	
	static function model($name) 
	{
		static $S_models = array();
		if(is_null($S_models[$name])) 
		{
			if(false === ($class_name = Load::file($name))) 
			{
				exit('model ' . $name . ' is not exists');
			}
			$S_models[$name] = new $class_name();
		}
		return $S_models[$name];
	}
	
	static function table($name) 
	{
		static $S_tables = array();
		if(is_null($S_tables[$name])) 
		{
			if(false === ($class_name = Load::file('table/' . $name))) 
			{
				if(($obj = jmodel('table'))) 
				{
					$obj->init($name);
					$S_tables[$name] = $obj;

					if(true === DEBUG) 
					{
						$f = ROOT_PATH . "s_include/class/table/" . $name . ".class.php";
						$fr = dirname($f) . "/[table].class.template";
						if(!file_exists($f) && file_exists($fr)) 
						{
							@file_put_contents($f, str_replace(array("[table]", ), array($name, ), file_get_contents($fr)));
						}
					}

					return $obj;
				}
				exit('table class ' . $name . ' is not exists');
			}
			$S_tables[$name] = new $class_name();
		}
		return $S_tables[$name];
	}
}


class Obj
{
	function &Obj($name=null)
	{
		Return Obj::_share($name, $null, 'get');
	}

	static function &_share($name=null,&$mixed,$type='set')
	{
		static $_register=array();
		if($name==null)
		{
			Return $_register;
		}
		if('get' == $type)
		{
			if(isset($_register[$name]))
			{
				Return $_register[$name];
			}

			return null;
		}
		if('set' == $type)
		{
			$_register[$name]=&$mixed;
		}
		return true;
	}
	
	static function register($name,&$obj)
	{
		Obj::_share($name,$obj,"set");
	}
	
	static function &registry($name=null)
	{
		Return Obj::_share($name,$null,'get');
	}
	
	static function isRegistered($name)
	{
		Return isset($_register[$name]);
	}
}

/**
 * 配置的读取及写入
 *
 */

class ConfigHandler 
{
	function ConfigHandler() {;}
	
	static function file($type=null) 
	{
		if($type) $type = str_replace(array('.','\\','/',),'',$type);
		return ROOT_PATH . 's_setting/' .($type===null?'settings':$type).'.php';
	}
	
	static function core_settings($local = null, $db = null, $act = 'merge') 
	{
		$_local = array(
			'auth_key' => 1,
			'charset' => 1,
			'db_host' => 1,
			'db_port' => 1,
			'db_name' => 1,
			'db_user' => 1,
			'db_pass' => 1,
			'db_table_prefix' => 1,
			'db_slave' => 1,
			'install_lock_time' => 1,
			'SERVER_founder' => 1,
			'memory_enable' => 1,
			'memory' => 1,
			'no_record_guest' => 0,
			'safe_key' => 1,
			'setting_from_db' => 1,
			'upgrade_lock_time' => 1,
			'upgrade_to_lock_version' => 1,
		);
		
		if(is_null($local)) 
		{
			include(ConfigHandler::file());
			$local = $config;
		}
		
		settype($local, 'array');
		settype($db, 'array');
		
		$rets = array_merge($local, $db);
		if('merge' == $act) 
		{
			foreach($_local as $k=>$v) 
			{
				$rets[$k] = $local[$k];
			}
		} 
		
		return $rets;
	}


	static function get() 
	{
		global $_J;
		
		$config = array();
		$type = null;
		$func_num_args = func_num_args();
		if(0 === $func_num_args || (($func_args = func_get_args()) && is_null(($type = $func_args[0])))) 
		{
			//if(!$_J['config']['auth_key']) 
			{
				@include(ConfigHandler::file());
				if($config) 
				{
					$_J['config'] = $config;
					$_J['config'] = ConfigHandler::core_settings($_J['config']);
				} 
				else 
				{
					$_J['config']['auth_key'] = random(32);
				}
			}
			return $_J['config'];
		} 
		else 
		{
			if(!isset($_J['config'][$type])) 
			{
				$_local = array('modules'=>1, 'theme'=>1, 'table'=>1, 'search_admin_menu_index'=>1, );
				/*
				if($_J['config']['setting_from_db'] && !isset($_local[$type])) 
				{
					$config[$type] = ConfigHandler::db($type);
				} 
				else 
				*/
				//{
					@include(ConfigHandler::file($type));
				//}
				
				if(!isset($config[$type])) 
				{
					$config[$type] = array();
				}
				
				$_J['config'][$type] = $config[$type];
			}
			
			if($func_num_args===1) 
			{
				return $_J['config'][$type];
			}
			
			if(isset($_J['config'][$type])) 
			{
				$path_str = '';
				foreach($func_args as $arg) 
				{
					$arg = str_replace(array(';', '"', "'", ), '', $arg);
					$path_str.="['$arg']";
				}
				
				return eval('return $_J["config"]' . $path_str . ";");
			}
		}
		return null;
	}

	
	static function set() 
	{
		$func_args=func_get_args();
		$value=array_pop($func_args);
		$type=array_shift($func_args);
		
		ConfigHandler::backup($type);
		$file=ConfigHandler::file($type);
		$data = '';
		if($type===null) 
		{
			if($value && $value['auth_key']) 
			{
				ksort($value);
				$keeps = array(
					'acceleration_mode' => 1,
					'charset' => 1,
					'db_host' => 1,
					'db_port' => 1,
					'db_name' => 1,
					'db_user' => 1,
					'db_pass' => 1,
					'db_table_prefix' => 1,
					'db_slave' => 1,
					'SERVER_founder' => 1,
					'setting_from_db' => 1,
				);
								
				foreach($keeps as $k=>$v) 
				{
					if($v && isset($value[$k]) && $value[$k] != $GLOBALS['_J']['config'][$k]) 
					{
						$value[$k] = $GLOBALS['_J']['config'][$k];
					}
				}
				if(true === DEBUG) 
				{ 					
					jlib("io")->WriteFile(ROOT_PATH . "s_setting/settings.default.php", "<?php \$config = ".var_export($value, true)."; ?>");
				}
				ConfigHandler::db(null, $value);
				$data="<?php \r\n 
				\r\n \$config = ".var_export(ConfigHandler::core_settings($value, array(), 'local'), true)."; \r\n?>";
			}
		} 
		else 
		{
			global $_J;

			$config = ConfigHandler::get($type);
			$path_str = '';
			foreach($func_args as $arg) 
			{
				$arg = str_replace(array(';', '"', "'", ), '', $arg);
				$path_str.="['$arg']";
			}
			eval($value===null?'unset($config'.$path_str.');':'$config'.$path_str.'=$value;');
			if(!is_null($config) && $_J['config'][$type] != $config) 
			{
				$_J['config'][$type] = $config;
				ConfigHandler::db($type, $config);
				$data="<?php \r\n 
				\r\n \$config['{$type}'] = ".var_export($config, true)."; \r\n?>";
			}
		}

		if($data) 
		{
			$len = jlib('io')->WriteFile($file, $data);
			if(false === $len) 
			{
				die($file." 文件无法写入,请检查是否有可写权限。");
			}
		}

		return $len;
	}

	static function update($var, $val=null) 
	{
		if(!$var) 
		{
			return array();
		}
		$arrs = array();
		if(is_array($var)) 
		{
			$arrs = $var;
		} 
		else 
		{
			$arrs[$var] = $val;
		}

		$update = 0;
		$config = ConfigHandler::core_settings();
		if($config) 
		{
			foreach($arrs as $var=>$val) 
			{
				if(is_array($val)) 
				{
					foreach ($val as $key=>$value) 
					{
						if($config[$var][$key] != $value) 
						{
							$update = 1;
							$config[$var][$key] = $value;
						}
					}
				} 
				else 
				{
					if($config[$var] != $val) 
					{
						$update = 1;
						$config[$var] = $val;
					}
				}
			}
		}
		if($update && $config) 
		{
			ConfigHandler::set($config);
		}
		return $config;
	}
}

class DB
{
	static function table($table)
	{
		$table_name = TABLE_PREFIX.$table;
		return $table_name;
	}

	static function where($condition, $glue=' AND ') 
	{
		if(empty($condition)) 
		{
			$where = '';
		} 
		elseif(is_array($condition)) 
		{
			$where = ' WHERE ' . DB::field($condition, $glue, 1);
		} 
		else 
		{
			$where = ' ' . (false!==strpos(strtoupper($condition), 'WHERE ') ? $condition : 'WHERE ' . $condition);
		}
		$where .= ' ';
		return $where;
	}

	static function delete($table, $condition, $limit = 0, $unbuffered = true)
	{
		$sql = "DELETE FROM ".DB::table($table).DB::where($condition).($limit ? "LIMIT $limit" : '');
		return DB::query($sql, ($unbuffered ? 'UNBUFFERED' : ''));
	}
	
	static function insert($table, $data, $return_insert_id = false, $replace = false, $silent = false)
	{
		$sql = DB::field($data);
		$cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';
		$table = DB::table($table);
		$silent = $silent ? 'SILENT' : '';
		$return = DB::query("$cmd $table SET $sql", $silent);
		return $return_insert_id ? DB::insert_id() : $return;
	}
	
	static function update($table, $data, $condition, $unbuffered = false, $low_priority = false)
	{
		$sql = DB::field($data);
		$cmd = "UPDATE ".($low_priority ? 'LOW_PRIORITY' : '');
		$table = DB::table($table);
		$res = DB::query("$cmd $table SET $sql ".DB::where($condition), $unbuffered ? 'UNBUFFERED' : '');
		
		return $res;
	}
	
	static function field($array, $glue = ',', $is_where=0) 
	{
		$sql = $comma = '';
		foreach ($array as $k => $v) 
		{
			$s = '';
			if(is_array($v)) 
			{
				$g = $v['glue'];
				if($g) 
				{
					$kk = ($v['key'] ? $v['key'] : $k);
					$vv = $v['val'];
					switch ($g) 
					{
						case '=':
						case '>':
						case '<':
						case '<>':
						case '>=':
						case '<=':
							$s = "`{$kk}`{$g}'{$vv}'";
							break;
						case '-':
						case '+':
						case '|':
						case '&':
						case '^':
							$s = "`{$kk}`=`{$kk}`{$g}'{$vv}'";
							break;
						case 'like':
							$s = "`{$kk}` LIKE('{$vv}')";
							break;
						case 'in':
						case 'notin':
							$s = "`{$kk}`".('notin'==$g ? ' NOT' : '')." IN(".jimplode($vv).")";
							break;
						default:
							exit("glue $g is invalid");
					}
				} 
				else 
				{
					if($is_where) 
					{
						$s = "`{$k}` IN(".jimplode($v).")";
					}
				}
			} 
			else 
			{
				$s = "`{$k}`='$v'";
			}

			if($s) 
			{
				$sql .= $comma . $s;
				$comma = $glue;
			}
		}
		return $sql;
	}

	static function insert_id()
	{
		return DB::_execute('Insert_ID');
	}

	static function fetch($resourceid, $type = 'assoc')
	{
		return DB::_execute('GetRow', $resourceid, $type);
	}
	
	static function fetch_first($sql)
	{
		return DB::_execute('FetchFirst', $sql);
	}

	static function fetch_all($sql, $keyfield='') 
	{
		return DB::_execute('FetchAll', $sql, $keyfield);
	}

	static function result($resourceid, $row = 0)
	{
		return DB::_execute('result', $resourceid, $row);
	}

	static function result_first($sql)
	{
		$query = DB::query($sql);
		return DB::result($query);
	}

	static function query($sql, $type = '')
	{
		return DB::_execute('Query', $sql, $type);
	}

	static function num_rows($resourceid)
	{
		return DB::_execute('GetNumRows', $resourceid);
	}

	static function affected_rows()
	{
		return DB::_execute('AffectedRows');
	}

	static function free_result($query)
	{
		return DB::_execute('FreeResult', $query);
	}

	static function error()
	{
		return DB::_execute('GetLastErrorString');
	}

	static function errno() 
	{
		return DB::_execute('GetLastErrorNo');
	}
	
	static function _execute($cmd , $arg1 = '', $arg2 = '') 
	{
		static $db=null;
		if(empty($db)) 
		{
			$db = & DB::object();
		}
		if ($cmd == 'GetRow') 
		{
			if(is_object($arg1)) 
			{
				$res = $arg1->GetRow($arg2);
			}
		} 
		else if ($cmd == 'result') 
		{
			if(is_object($arg1)) 
			{
				$res = $arg1->result($arg2);
			}
		} 
		else if ($cmd == 'GetNumRows') 
		{
			if(is_object($arg1)) 
			{
				$res = $arg1->GetNumRows();
			}
		} 
		else if ($cmd == 'FreeResult') 
		{
			if(is_object($arg1)) 
			{
				$res = $arg1->FreeResult();
			}
		} 
		else 
		{
			if(is_object($db)) 
			{
				$res = $db->$cmd($arg1, $arg2);
			}
		}
		return $res;
	}

	static function &object() 
	{
		static $db=null;
		if(empty($db)) 
		{
			$db = & Obj::registry('DatabaseHandler');
			if (empty($db)) 
			{
				include(ROOT_PATH . 's_setting/settings.php');
				include_once ROOT_PATH . 's_include/db/database.db.php';
				include_once ROOT_PATH . 's_include/db/mysql.db.php';
				$db = new MySqlHandler();
				
				$db->do_connect($config['db_host'], $config['db_port'],
								$config['db_user'], $config['db_pass'],
								$config['charset'], $config['db_name'],
								isset($config['db_persist']) ? $config['db_persist'] : $config['db_pconnect']);
				Obj::register('DatabaseHandler', $db);
			}
		}
		return $db;
	}
	
	static function checkquery($sql) 
	{
		return DB::_execute('CheckQuery');
	}
}


function get_list($table_name, $parma)
{
	$where_sql = ' 1 ';
	$order_sql = ' ';
	$limit_sql = ' ';
	if (empty($parma['field'])) 
	{
		$field = ' * ';
	} 
	else 
	{
		$field = $parma['field'];
	}
	if (!empty($parma['where'])) 
	{
		$where_sql .= " AND {$parma['where']} ";
	}
	if (!empty($parma['order'])) 
	{
		$order_sql = " ORDER BY {$parma['order']} ";
	}
	if (!empty($parma['limit'])) 
	{
		$limit_sql = " LIMIT {$parma['limit']} ";
	}

	$count = DB::result_first("SELECT COUNT(*) FROM ".DB::table($table_name)." WHERE {$where_sql}");
	$keyword_ary = array();
	if ($count) 
	{
		if ($parma['page']) 
		{
			$_config = array(
				'return' => 'array',
			);
			$page_ary = page($count, $parma['perpage'], $parma['page_url'], $_config);
			$limit_sql = $page_ary['limit'];
		}
		$query = DB::query("SELECT {$field} FROM ".DB::table($table_name)." WHERE {$where_sql} {$order_sql} {$limit_sql}");
		while ($value = DB::fetch($query)) 
		{
			$keyword_ary[] = $value;
		}
		$r = array('list' => $keyword_ary, 'count' => $count);
		if ($parma['page']) 
		{
			$r['page'] = $page_ary['html'];
		}
		return $r;
	}
	return false;
}


function table_exists($table_name)
{
	$row = DB::fetch_first("SHOW TABLES LIKE '".DB::table($table_name)."'");
	if (empty($row)) 
	{
		return false;
	}
	return true;
}

$__TMP_OBJ_OF_UPS_CTRL = null;
function sys_version($v = null) 
{
	$v = ($v ? $v : SYS_VERSION);
	return $v;

	$srp = strrpos($v, '.');
	if(false !== $srp) 
	{
		$v = substr($v, 0, $srp);
	}
	return $v;
}

function dir_safe($dir, $safe=1) 
{
	if($safe) 
	{
		$search1 = array('..', '*', '?', '"', '<', '>', '|',  );
		$dir = str_replace($search1, '', $dir);
		$dir = str_replace($search1, '', $dir);
	}
	if(false !== strpos($dir, '/')) 
	{
		$search2 = array('\\', '/./', '/'.'/'.'/'.'/', '/'.'/'.'/', '/'.'/', );
		$dir = str_replace($search2, '/', $dir);
		$dir = str_replace($search2, '/', $dir);
	}

	return $dir;
}

function str_safe($str) 
{
	$str = trim(strip_tags($str));
	if($str) 
	{
		return jhtmlspecialchars(trim(str_replace(array('&gt;','<','&lt;','>','"',"'",'%3C','%3E','%22','%27','%3c','%3e'), '', $str)));
	}
	return '';
}


// Originally written by xellisx
function parse_query($var)
{
	/**
	 *  Use this function to parse out the query array element from
	 *  the output of parse_url().
	 */
	$var  = parse_url($var, PHP_URL_QUERY);
	$var  = html_entity_decode($var);
	$var  = explode('&', $var);
	$arr  = array();

	foreach($var as $val)
	{
		$x          = explode('=', $val);
		$arr[$x[0]] = $x[1];
	}
	unset($val, $x, $var);
	return $arr;
}

function GetIP()
{
	$cip ="";
	if(!empty($_SERVER["HTTP_CLIENT_IP"]))
	{
		$cip = $_SERVER["HTTP_CLIENT_IP"];
	}
	elseif(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
	{
		$cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
	}
	elseif(!empty($_SERVER["REMOTE_ADDR"]))
	{
		$cip = $_SERVER["REMOTE_ADDR"];
	}
	return $cip;
}

?>